﻿using Nantianmen.Domain.Models;
using Nantianmen.Shared;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Nantianmen.Core.Stores
{
    public abstract class ClusterStoreBase : StoreBase, IClusterStore, IClusterDestinationStore, IQueryableClusterStore
    {
        public NantianmenErrorDescriber ErrorDescriber { get; set; }

        public ClusterStoreBase(NantianmenErrorDescriber errorDescriber)
        {
            ArgumentNullException.ThrowIfNull(errorDescriber);
            ErrorDescriber = errorDescriber;
        }

        public abstract IQueryable<Cluster> Clusters { get; }
        public abstract Task AddToDestinationAsync(Cluster cluster, string destinationId, CancellationToken cancellationToken);
        public abstract Task<bool> CheckDuplicateClusterIdAsync(string clusterId, CancellationToken cancellationToken);
        public abstract Task<NantianmenResult> CreateAsync(Cluster cluster, CancellationToken cancellationToken);
        public abstract Task<List<Cluster>> GetClustersAsync(CancellationToken cancellationToken);
        public abstract Task<bool> HasDestinationAsync(Cluster cluster, string destinationId, CancellationToken cancellationToken);
        public abstract Task RemoveFromDestinationAsync(Cluster cluster, string destinationId, CancellationToken cancellationToken);
        public abstract Task<NantianmenResult> UpdateAsync(Cluster cluster, CancellationToken cancellationToken);

        protected virtual ClusterDestination CreateClusterDestination(Cluster cluster, string destinationId)
        {
            return new ClusterDestination
            {
                ClusterId = cluster.Id,
                DestinationId = destinationId,
            };
        }

        public abstract Task<bool> CheckDuplicateClusterDestinationAsync(string clusterId, string destinationId, CancellationToken cancellationToken);
        public abstract Task<Cluster?> FindClusterByIdAsync(string clusterId, CancellationToken cancellationToken);
        public abstract Task<NantianmenResult> RemoveAsync(Cluster cluster, CancellationToken cancellationToken);
        public abstract Task<List<Destination>> FindClusterDestinationsAsync(string clusterId, CancellationToken cancellationToken);
    }
}
